package repositories

import (
	"context"
	"strings"

	"gorm.io/gorm"

	"github.com/samaa/photosalesplus/backend/internal/models"
)

type UserRepository interface {
	Create(ctx context.Context, user *models.User) error
	FindByUsername(ctx context.Context, username string) (*models.User, error)
	FindByID(ctx context.Context, id uint) (*models.User, error)
	DeleteByID(ctx context.Context, id uint) error
	UpdateRole(ctx context.Context, id uint, role string) error
	UpdateProfile(ctx context.Context, id uint, displayName *string, avatarURL *string) error
}

type userRepository struct {
	db *gorm.DB
}

func NewUserRepository(db *gorm.DB) UserRepository {
	return &userRepository{db: db}
}

func (r *userRepository) Create(ctx context.Context, user *models.User) error {
	return r.db.WithContext(ctx).Create(user).Error
}

func (r *userRepository) FindByUsername(ctx context.Context, username string) (*models.User, error) {
	var user models.User
	if err := r.db.WithContext(ctx).Where("username = ?", username).First(&user).Error; err != nil {
		return nil, err
	}
	return &user, nil
}

func (r *userRepository) FindByID(ctx context.Context, id uint) (*models.User, error) {
	var user models.User
	if err := r.db.WithContext(ctx).First(&user, id).Error; err != nil {
		return nil, err
	}
	return &user, nil
}

func (r *userRepository) DeleteByID(ctx context.Context, id uint) error {
	return r.db.WithContext(ctx).Delete(&models.User{}, id).Error
}

func (r *userRepository) UpdateRole(ctx context.Context, id uint, role string) error {
	return r.db.WithContext(ctx).Model(&models.User{}).Where("id = ?", id).Update("role", role).Error
}

func (r *userRepository) UpdateProfile(ctx context.Context, id uint, displayName *string, avatarURL *string) error {
	updates := make(map[string]interface{})

	if displayName != nil {
		name := strings.TrimSpace(*displayName)
		updates["display_name"] = name
	}

	if avatarURL != nil {
		url := strings.TrimSpace(*avatarURL)
		updates["avatar_url"] = url
	}

	if len(updates) == 0 {
		return nil
	}

	return r.db.WithContext(ctx).Model(&models.User{}).Where("id = ?", id).Updates(updates).Error
}
